//修饰器是一个函数，用来修改类的行为

// A = {a:3}

{
  let readonly = function <T>(
    target: T,
    name: string,
    descriptor: PropertyDescriptor
  ) {
    descriptor.writable = false;
    return descriptor;
  };
  class Test {
    @readonly
    time() {
      return "2019-05-03";
    }
  }
  let test = new Test();
  // test.time = function(){
  //     console.log('reset time')
  // }   报错，readonly property
  console.log(test.time()); //2019-05-03
}

{
  let typename = (constructor: typeof Test) => {
    // target.myname = 'yycf';
    console.dir(constructor);
    constructor.myname = "yycf";
  };
  @typename
  class Test {
    static myname: string;
  }
  console.dir(Test.myname); // yycf
  //第三方库修饰器的js库：core-decorators //npm i core-decorators
}

{
  //好处1. 把埋点系统抽离出来，成为一个可复用的模块,将来埋点接口变了，只用改log方法 广告类几乎不动
  //2.埋点系统从业务逻辑中剥离出去，业务代码更简洁便于维护
  let log = (type: string) => {
    return <T>(target: T, name: string, descriptor: PropertyDescriptor) => {
      let src_method = descriptor.value;
      descriptor.value = (...arg: any[]) => {
        src_method.apply(target, arg);
        // 模拟埋点  埋点后执行
        //在真实的业务中一般为 new Image().src  然后一个接口
        console.info(`log ${type}`);
      };
    };
  };
  class AD {
    @log("show")
    show() {
      console.log("ad is show");
    }
    @log("click")
    click() {
      console.info("ad is click");
    }
  }
  let ad = new AD();
  ad.show();
  ad.click();
}
